/**
 * Server.java
 * 
 * (C) 2011 - Mischa Spelt (m.spxxxelt@gmail.com - remove xxx)
 * 
 */
package com.mischa.network;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Server - an abstract base class handling client
 * connections.
 *  
 * @author Mischa Spelt
 *
 */
public abstract class Server {
	/**
	 * The port to listen on for incoming connections.
	 */
	private int _port;

	/**
	 * The socket to listen on for incoming conections.
	 */
	private ServerSocket _socket = null;
	
	/**
	 * Flag to indicate whether we still accept connections.
	 */
	private volatile boolean _running = true;

	/**
	 * Constructor
	 * 
	 * @param port
	 * 		The port to listen on for incoming connections.
	 */
	public Server(int port) {
		_port = port;		
	}
	
	/**
	 * Start listening for incoming connections.
	 * 
	 * @throws IOException
	 * 		if an error occurs when connecting a client or closing the socket.
	 */
	public void start() throws IOException
	{
		_socket = new ServerSocket(_port);
		
		Thread thread = new Thread()
		{
			@Override
			public void run() {
				try
				{
					while(_running)
					{
						try
						{						
							clientConnected(_socket.accept());						
						}
						catch (IOException exception)
						{
							System.out.println("Could not accept client connection: " + exception.getMessage());
						}
					}
				}
				finally
				{
					try {
						_socket.close();
					} catch (IOException e) {
						// Do nothing						
					}
				}
			}
		};
		
		thread.start();
	}
	
	/**
	 * Stop listening for incoming connections. 
	 * May not respond immediately.
	 */
	public void stop()
	{
		_running = false;
	}
	
	/**
	 * Method that is called when a client has connected.
	 * Intended to be overridden and create a proper handler that will
	 * communicate with the client from now on.
	 * 
	 * @param socket
	 * 		The socket that the client is listening to and writing into.
	 */
	public abstract void clientConnected(Socket socket);
}
